import VideoAbstract from './VideoAbstract';
import type { PropsType } from './CommonVideoPlayer';

export default class DhHlsVideo extends VideoAbstract {
	private static instance: DhHlsVideo | null;

	private hls: Window['dhhlsjs'] | null;
	private videoElement: HTMLVideoElement | undefined;

	private constructor(props: PropsType['dhhls']) {
		super();
		this.hls = new window.dhhlsjs();
		this.loadSource(props.url);
		this.bindVideo(props.el);

		this.hls.on(window.dhhlsjs.Events.MEDIA_ATTACHED, () => {
			// 元素绑定成功
			console.log('dhhls元素绑定成功');
		});

		console.log('dhhls实例化成功');
	}

	static getInstance(props: PropsType['dhhls']): DhHlsVideo {
		return DhHlsVideo.instance || (DhHlsVideo.instance = new DhHlsVideo(props));
	}

	loadSource(url: string) {
		this.hls?.loadSource(url);
	}

	bindVideo(video: HTMLVideoElement): void {
		this.videoElement = video;
		this.hls?.attachMedia(video);
	}

	unbindVideo(): void {
		this.hls?.detachMedia();
	}

	setCurrentTime(time: number): void {
		this.hls?.startLoad(time);
	}

	play(): void {
		if (this.videoElement) this.videoElement.play();
	}

	pause(): void {
		if (this.videoElement) this.videoElement.pause();
	}

	destroy(): void {
		if (this.hls !== null) {
			this.hls?.off(window.dhhlsjs.Events.MEDIA_ATTACHED);
			this.hls?.off(window.dhhlsjs.Events.MANIFEST_PARSED);
			this.hls?.off(window.dhhlsjs.Events.ERROR);
			this.unbindVideo();
			this.hls?.destroy();
			this.hls = null;
		}
		DhHlsVideo.instance = null;
	}

	onLoaded(callback: (data: any) => void): void {
		this.hls?.on(window.dhhlsjs.Events.MANIFEST_PARSED, (e: any) => {
			console.log('dhhls-loaded', e);
			setTimeout(() => {
				if (typeof callback === 'function') callback(e.levels);
			}, 300);
		});
	}

	// 播放中
	onPlaying(callback: (data: any) => void): void {
		this.hls?.on(window.dhhlsjs.Events.FRAG_CHANGED, (_: any, data: any) => {
			if (typeof callback === 'function') callback(data);
		});
	}

	// 播放完成
	onPlayEnd(callback: (data: any) => void): void {
		this.videoElement?.addEventListener('ended', (e) => {
			callback(e);
		});
	}

	onError(callback?: (error: any) => void): void {
		this.hls?.on(window.dhhlsjs.Events.ERROR, (event: any, data: any) => {
			console.error('dhhls-error', event, data);
			if (typeof callback === 'function') callback(data);
		});
	}
}
